﻿using System.Reflection.Emit;
using System;
using System.Reflection;
using System.Linq;
using System.Collections.Generic;

namespace ProxyViewModel.Emitors {
	public class ConstructorsEmitor : EmitorBase {
		public ConstructorsEmitor(TypeBuilder builder, Type operatable, IDictionary<string, object> parameters) :
			base(builder, operatable, parameters) { }

		protected override void EmitContent() {
			ConstructorInfo [] constructors = Operatable.GetConstructors(BindingFlags.Public | BindingFlags.Instance);
			constructors.ToList().ForEach(e => EmitConstructor(e));
		}

		private void EmitConstructor(ConstructorInfo inputConstructor) {
			ConstructorBuilder constructor = TypeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard,
				inputConstructor.GetParameters().Select(e => e.ParameterType).ToArray(), null, null);
			ILGenerator generator = constructor.GetILGenerator();
			generator.Emit(OpCodes.Ldarg_0);
			for (int i = 0; i < inputConstructor.GetParameters().Count(); ++i) {
				generator.Emit(OpCodes.Ldarg, i + 1);
			}
			generator.Emit(OpCodes.Call, inputConstructor);

			if (GetParameter<List<MethodInfo>>(Parameters.MethodsToCallOnConstructionKey) != null) {
				foreach (MethodInfo info in GetParameter<List<MethodInfo>>(Parameters.MethodsToCallOnConstructionKey)) {
					generator.Emit(OpCodes.Ldarg_0);
					generator.Emit(OpCodes.Call, info);
				}
			}
			
			generator.Emit(OpCodes.Ret);
		}
	}
}
